package com.gorillalogic.scrummonkey.dms {
	
	import com.adobe.fiber.core.model_internal;	

	[RemoteClass(alias="ScrumDMS.Objective")]
	public class Objective extends _Super_Objective {
		/** 
		 * DO NOT MODIFY THIS STATIC INITIALIZER - IT IS NECESSARY
		 * FOR PROPERLY SETTING UP THE REMOTE CLASS ALIAS FOR THIS CLASS
		 *
		 **/
		
		/**
		 * Calling this static function will initialize RemoteClass aliases
		 * for this value object as well as all of the value objects corresponding
		 * to entities associated to this value object's entity.  
		 */     
		public static function _initRemoteClassAlias() : void
		{
			_Super_Objective.model_internal::initRemoteClassAliasSingle(com.gorillalogic.scrummonkey.dms.Objective);
			_Super_Objective.model_internal::initRemoteClassAliasAllRelated();
		}
		
		model_internal static function initRemoteClassAliasSingleChild() : void 
		{
			_Super_Objective.model_internal::initRemoteClassAliasSingle(com.gorillalogic.scrummonkey.dms.Objective);
		}
		
		{
			_Super_Objective.model_internal::initRemoteClassAliasSingle(com.gorillalogic.scrummonkey.dms.Objective);
		}
		/** 
		 * END OF DO NOT MODIFY SECTION
		 *
		 **/    
		
		public function Objective(name:String=null,description:String=null) {
			super();
			this.name = name;
			this.description = description;
		}

		/** Assign objective to given target in the hierarchy, and if
		 *  necessary unassign from old target AND all of the old target's
		 *  children.
		 */
		public function assign(target:Object):void {
			if (target is Project) {
				if (this.project != null) {
					throw new Error('Objective can NOT be re-assigned to a different project!');
				}
				this.project = target as Project;
			} else if (target is Release) {
				if (this.release != null) {
					//unassign from current release & any child iterations of current release
					unassign(this.release);
				} else {
					if (this.project == null) {
						assign((target as Release).project);
					}
				}

				//assign to new release
				this.release = target as Release;
			} else if (target is Iteration) {
				if (this.iteration != null) {
					if (this.release != (target as Iteration).release) {
						//reassign to new release (which unassigns from all iterations)
						assign((target as Iteration).release);
					} else {
						//unassign from current iteration
						unassign(this.iteration);
					}
				} else {
					if (this.release == null || this.release != (target as Iteration).release) {
						//reassign to new release (which unassigns from all iterations)
						assign((target as Iteration).release);
					}
				}

				//assign to new iteration
				this.iteration = target as Iteration;
			} else {
				throw new Error('Invalid target for objective.assign()');
			}
			target.objectives.addItem(this);
		}

		/** Unassign objective from given target.  If target
		 *  is the project, then delete this objective.
		 */
		public function unassign(target:Object):void {
			if (target is Project) {
				//objectives must have a project, so delete them!
				ObjectiveService.service.deleteObjective(this);
			} else if (target is Release) {
				var targetRelease:Release = target as Release;

				//unassign from current release
				var i:int = targetRelease.objectives.getItemIndex(this);
				targetRelease.objectives.removeItemAt(i);

				//unassign from any child iterations
				if (this.iteration != null) {
					unassign(this.iteration);
				}

				this.release = null;
			} else if (target is Iteration) {
				var targetIteration:Iteration = target as Iteration;

				//unassign from current iteration
				var j:int = targetIteration.objectives.getItemIndex(this);
				targetIteration.objectives.removeItemAt(j);

				this.iteration = null;
			} else {
				throw new Error('Invalid target for objective.unassign()');
			}
		}
	}
}